import unittest
import os
import tempfile
from wc import (
    count_chars, count_words, count_sentences,
    count_code_lines, count_empty_lines, count_comment_lines
)


class TestWCNormalCases(unittest.TestCase):

    def setUp(self):
        self.test_dir = os.path.join(os.path.dirname(__file__), "texts")
        self.normal_file = os.path.join(self.test_dir, "normal.txt")
        self.empty_file = os.path.join(self.test_dir, "empty.txt")
        self.code_file = os.path.join(self.test_dir, "code.py")
        self.special_file = os.path.join(self.test_dir, "special_chars.txt")

    def test_count_chars(self):
        self.assertEqual(count_chars(self.normal_file), 28)
        self.assertEqual(count_chars(self.empty_file), 0)

    def test_count_words(self):
        self.assertEqual(count_words(self.normal_file), 5)
        self.assertEqual(count_words(self.empty_file), 0)

    def test_count_sentences(self):
        self.assertEqual(count_sentences(self.normal_file), 2)
        self.assertEqual(count_sentences(self.special_file), 3)
        self.assertEqual(count_sentences(self.empty_file), 0)

    def test_count_code_lines(self):
        self.assertEqual(count_code_lines(self.code_file), 2)

    def test_count_empty_lines(self):
        self.assertEqual(count_empty_lines(self.code_file), 1)

    def test_count_comment_lines(self):
        self.assertEqual(count_comment_lines(self.code_file), 1)


class TestWCErrorCases(unittest.TestCase):

    def test_file_not_found(self):
        with self.assertRaises(SystemExit) as cm:
            count_chars("不存在的文件.txt")
        self.assertEqual(cm.exception.code, 1)

    def test_gbk_encoded_file(self):
        gbk_file = os.path.join(os.path.dirname(__file__), "texts", "gbk_encoded.txt")
        with self.assertRaises(SystemExit) as cm:
            count_chars(gbk_file)
        self.assertEqual(cm.exception.code, 1)

    def test_permission_denied(self):
        with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
            f.write("test")
            temp_name = f.name
        os.chmod(temp_name, 0o444)
        try:
            with self.assertRaises(SystemExit) as cm:
                count_chars(temp_name)
            self.assertEqual(cm.exception.code, 1)
        finally:
            os.chmod(temp_name, 0o666)
            os.remove(temp_name)


if __name__ == '__main__':
    unittest.main()